/*
 * Copyright (c) 2020, yifengling0. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. No personal names or organizations' names associated with the
 *    Atomthreads project may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "atom.h"
#include "console.h"
#include "pwm.h"
#include "device.h"
#include "beep.h"
#include "kassert.h"
#include "syslog.h"

int DeviceBeepSet(DeviceBeep *dev, uint16_t freq, uint8_t volume)
{
    int ret;
    uint32_t period, pulse;

    kassert(dev != NULL);

    /* 将频率转化为周期 周期单位:ns 频率单位:HZ */
    period = 1000000000 / freq;  //unit:ns 1/HZ*10^9 = ns

    /* 根据声音大小计算占空比 蜂鸣器低电平触发 */
    pulse = period - period / 100 * volume;

    /* 利用 PWM API 设定 周期和占空比 */
    ret = PwmSet(dev->Protected.pwm, dev->Protected.channel, period, pulse);//channel,period,pulse

    dev->Protected.freq = freq;
    dev->Protected.volume = volume;

    return ret;
}

int DeviceBeepEnable(DeviceBeep *dev, int enable)
{
    int ret;

    kassert(dev != NULL);

    if( enable ){
        ret = PwmEnable(dev->Protected.pwm, dev->Protected.channel);
    }else{
        ret = PwmDisable(dev->Protected.pwm, dev->Protected.channel);
    }

    return ret;
}

void DeviceBeepCreate(DeviceBeep *dev, const DeviceDesc *desc)
{
    DeviceInstall(&dev->super, desc);
    dev->Protected.init(dev);

    SYSLOG(LOG_INFO, "device %s initlized", desc->name);
}